package com.house.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.house.entity.Area;
import com.house.mapper.AreaMapper;
import com.house.service.AreaService;
import com.house.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AreaServiceImpl implements AreaService {

    private final String AREAS = "areas";

    private final int[] levels = {5,4,3,2,1,0};

    @Value("${spring.cache.redis.time-to-live}")
    private Integer timeout;

    @Autowired
    private AreaMapper areaMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public int save(Area area) {
        // 更新和添加区域清除区域缓存
        List<Area> areas = redisUtil.getCacheObject(AREAS);
        if (areas == null) {
            getAreas();
            areas = redisUtil.getCacheObject(AREAS);
        }
        // 增长的数量
        long addNum = 1;
        for (int i = 0; i < levels[area.getLevel()]; i++) {
            addNum = addNum * 100;
        }
        long maxSiblingAreaId;
        long areaId;
        List<Area> siblingAreas = areas.stream().filter((Area item) -> area.getParentId() == item.getParentId()).sorted((x, y) -> Math.toIntExact(y.getAreaId() - x.getAreaId())).collect(Collectors.toList());
        if ("[]".equals(siblingAreas.toString())) {
            maxSiblingAreaId = addNum * 10;
            areaId = maxSiblingAreaId + addNum + area.getParentId();
        } else {
            maxSiblingAreaId = siblingAreas.get(0).getAreaId();
            areaId = maxSiblingAreaId + addNum;
        }
        area.setAreaId(areaId);
        int res = areaMapper.insert(area);
        redisUtil.deleteObject(AREAS);
        return res;
    }

    @Override
    public int update(Area area) {
        LambdaQueryWrapper<Area> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Area::getAreaId, area.getAreaId());
        int res = areaMapper.update(area, queryWrapper);
        redisUtil.deleteObject(AREAS);
        return res;
    }

    @Override
    public List<Area> getAreas() {
        List<Area> areas = redisUtil.getCacheObject(AREAS);
        if (areas != null) {
            return areas;
        }
        areas = areaMapper.selectAreas();
        redisUtil.setCacheObject(AREAS, areas, timeout, TimeUnit.SECONDS);
        return areas;
    }

    @Override
    public int delete(int areaId) {
        int res = areaMapper.delete(areaId);
        redisUtil.deleteObject(AREAS);
        return res;
    }
}
